
<template>
  <div
    class="tops"
    v-loading.fullscreen.lock="loading"
    :element-loading-text="loadingText"
  >
    <!-- <IndexMenus /> -->
    <div class="topss">
      <Menus
        :input="input"
        :list="list"
        @pptimg="pptimg"
        @compound="compound"
        @refercanto="refercanto"
        @canreferto="canreferto"
        @conserve="conserve"
        @pptupok="pptupok"
        @pptlistarrsay="pptlistarrsay"
        @pptlist="pptlist"
        @emptypptimg="emptypptimg"
        @emptycompound="emptycompound"
      />
    </div>
    <div class="home">
      <div class="tabssab">
        <el-tabs
          type="border-card"
          v-model="activeNamethird"
          :tab-position="tabPositions"
        >
          <!-- <el-tab-pane label="效果图预览" name="third">
        </el-tab-pane> -->
          <el-tab-pane name="PPTList">
            <span slot="label" class="panetext">
              <span class="el-icon-user">虚拟人</span>
            </span>
            <PPTList @userilst="userlist" />
          </el-tab-pane>
          <el-tab-pane name="Scene">
            <span slot="label" class="panetext">
              <span class="el-icon-money">场景</span>
            </span>
            <Scene
              @backgroun="backgroun"
              @clientside="clientside"
              @mobileclient="mobileclient"
              :flagscene="flagscene"
            />
          </el-tab-pane>
          <el-tab-pane name="Timbrelist">
            <span slot="label" class="panetext">
              <span class="el-icon-microphone">音色</span>
            </span>

            <Timbre @timbersingle="timbersingle" />
          </el-tab-pane>
          <!-- <el-tab-pane name="bgMusic">
            <span slot="label" class="panetext">
              <span class="el-icon-headset">背景音乐</span>
            </span>
            <BgMusic />
          </el-tab-pane> -->
          <!-- <el-tab-pane name="images">
            <span slot="label" class="panetext">
              <span class="el-icon-picture">图片</span>
            </span>
            <ImageS />
          </el-tab-pane> -->
        </el-tabs>
      </div>
      <div v-show="flagclient">
        <div class="carvas" ref="carvasa">
          <draggable
            class-name-dragging="my-dragging-class"
            class-name="my-class"
            style="z-index: 99"
            :active="true"
            v-for="(item, index) in ppttext[nums].textureList"
            :key="item.id"
            :parent="true"
            :x="item.x"
            :y="item.y"
            :w="item.width"
            :h="item.height"
            @resizestop="
              (left, top, width, height) =>
                onResizejpg(index, left, top, width, height)
            "
            @dragstop="(left, top) => onDragjpg(index, left, top)"
          >
            <el-image :src="url + item.path" class="imges"> </el-image>
          </draggable>
          <draggable
            class-name="my-class"
            class-name-dragging="my-dragging-class"
            :active="true"
            :parent="true"
            v-show="image[nums].img"
            :x="x"
            :y="y"
            :w="w"
            :h="h"
            @resizestop="onResize"
            @dragstop="onDrag"
          >
            <el-image
              v-if="!image[nums].video"
              :src="url + image[nums].img"
              class="imges"
            ></el-image>
            <video
              v-else
              controls
              :src="url + image[nums].video"
              class="imges"
            ></video>
          </draggable>
          <draggable
            class-name-dragging="my-dragging-class"
            class-name="my-class"
            :active="true"
            v-show="user.staticImg"
            :x="x1"
            :y="y1"
            :w="w1"
            :h="h1"
            @dragstop="onDraguser"
            @resizestop="usersize"
            :lockAspectRatio="true"
            :parent="true"
          >
            <!-- :resizable="false" 可调整大小-->
            <el-image :src="url + user.staticImg" class="imges">
              <div slot="placeholder" class="image-slot">
                加载中<span class="dot">...</span>
              </div>
            </el-image>
          </draggable>
        </div>
        <div class="bottoms">
          <div class="bottomsform">
            <div class="bottomsformtop">
              <div class="bottomsformleft">
                <el-button
                  v-show="pptttsflag"
                  type="primary"
                  @click="interpositionnode"
                  round
                  icon="el-icon-folder-opened"
                  :disabled="buttonsfalse"
                  v-if="isppts"
                  size="medium"
                  >插入元素</el-button
                >
                <div class="bottomsformleftringht" v-show="pptttsflag">
                  <span>音色：{{ timbresingle }}</span>
                </div>
              </div>
              <div class="bottomsformtopright">
                <div style="padding-right: 10px">
                  <el-button
                    icon="el-icon-edit-outline"
                    type="primary"
                    round
                    @click="removetts"
                    v-show="!pptttsflag"
                    size="medium"
                    >恢复文本模式</el-button
                  >
                </div>
                <div class="bottomsformtoprightleft">
                  <el-button
                    style="margin-right: 10px"
                    type="primary"
                    icon="el-icon-video-play"
                    @click="texttovideo(ppttext[nums].text)"
                    v-show="pptttsflag"
                    size="medium"
                    round
                    >试听</el-button
                  >
                  <el-upload
                    class="upload-demo"
                    :action="url + 'virtual/v1/userPro/resUpload'"
                    :data="upddsobj"
                    :before-upload="befoupload"
                    name="resource"
                    :on-success="successupppt"
                    accept=".wav,.mp3"
                    :show-file-list="false"
                  >
                    <el-button
                      icon="el-icon-upload2"
                      type="primary"
                      round
                      @click="ttspush"
                      size="medium"
                      >上传音频</el-button
                    ><span style="color: red; font-size: 12px">文本禁用</span>
                  </el-upload>
                  <el-button
                    icon="el-icon-video-camera-solid"
                    type="primary"
                    round
                    @click="ttspush(), dialogVisibleutles(), startCanvas()"
                    size="medium"
                    >录制音频 </el-button
                  ><span style="color: red; margin-top: 10px; font-size: 12px"
                    >文本禁用</span
                  >
                  <el-button
                    type="primary"
                    icon="el-icon-connection"
                    @click="textDomesScve(1)"
                    v-show="pptttsflag"
                    size="medium"
                    round
                    :loading="saveTextField"
                    >保存文本框</el-button
                  >
                </div>
              </div>
            </div>
            <div>
              <div v-show="pptVideos" style="margin: 50px 0 20px">
                <i class="el-icon-upload2"></i> 第{{ nums + 1 }}页PPT上传的音频
              </div>
              <div>
                <audio
                  controls
                  v-show="pptVideos"
                  :src="url + pptVideos"
                  ref="videoPlay"
                ></audio>
              </div>
            </div>
            <div v-show="pptttsflag">
              <div
                class="edotclass"
                id="edit"
                ref="editone"
                contenteditable
                @click="editClick"
                v-html="ppttext[nums].textdome"
              ></div>
              <div class="bottom">
                <audio
                  autoplay
                  v-show="Videos"
                  :src="url + Videos"
                  ref="videoPlay"
                ></audio>
                <div class="bottombtn">
                  <span>{{ canvastext }}/300</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div v-show="!flagclient">
        <div class="carvasflags backs">
          <div class="carvasflag" ref="carvas">
            <draggable
              class-name-dragging="my-dragging-class"
              class-name="my-class"
              style="z-index: 99"
              :active="true"
              v-for="(item, index) in ppttext[nums].textureList"
              :key="item.id"
              :parent="true"
              :x="item.x"
              :y="item.y"
              :w="item.width"
              :h="item.height"
              @resizestop="
                (left, top, width, height) =>
                  onResizejpg(index, left, top, width, height)
              "
              @dragstop="(left, top) => onDragjpg(index, left, top)"
            >
              <el-image :src="url + item.path" class="imges">
                <div slot="placeholder" class="image-slot">
                  加载中<span class="dot">...</span>
                </div></el-image
              >
            </draggable>
            <draggable
              class-name="my-class"
              class-name-dragging="my-dragging-class"
              :active="true"
              v-show="image[nums].img"
              :parent="true"
              :x="x"
              :y="y"
              :w="w"
              :h="h"
              @resizestop="onResize"
              @dragstop="onDrag"
            >
              <!-- :lock-aspect-ratio="true" -->
              <!-- :draggable="false" -->
              <!-- :resizable="false" -->
              <!-- @resizing="onResize"
          @dragging="onDrag" -->
              <el-image
                v-if="!image[nums].video"
                :src="url + image[nums].img"
                class="imges"
              >
                <div slot="placeholder" class="image-slot">
                  加载中<span class="dot">...</span>
                </div></el-image
              >
              <video
                v-else
                controls
                :src="url + image[nums].video"
                class="imges"
              ></video>
            </draggable>
            <draggable
              class-name="my-class"
              class-name-dragging="my-dragging-class"
              :active="true"
              v-show="user.staticImg"
              :x="x1"
              :y="y1"
              :w="w1"
              :h="h1"
              :parent="true"
              @dragging="onDraguser"
              @resizestop="usersize"
              :resizing="false"
              :lockAspectRatio="true"
            >
              <!-- :resizable="false" 可调整大小-->
              <el-image :src="url + user.staticImg" class="imges">
                <div slot="placeholder" class="image-slot">
                  加载中<span class="dot">...</span>
                </div>
              </el-image>
            </draggable>
          </div>
        </div>
        <div class="bottoms">
          <div class="bottomsform">
            <div class="bottomsformtop">
              <div class="bottomsformleft">
                <el-button
                  v-show="pptttsflag"
                  type="primary"
                  @click="update = true"
                  round
                  icon="el-icon-folder-opened"
                  :disabled="buttonsfalse"
                  v-if="isppts"
                  size="medium"
                  >插入元素</el-button
                >
                <div class="bottomsformleftringht" v-show="pptttsflag">
                  <span>音色：{{ timbresingle }}</span>
                </div>
              </div>
              <div class="bottomsformtopright">
                <div style="padding-right: 10px">
                  <el-button
                    icon="el-icon-edit-outline"
                    type="primary"
                    round
                    @click="removetts"
                    v-show="!pptttsflag"
                    size="medium"
                    >恢复文本模式</el-button
                  >
                </div>
                <div class="bottomsformtoprightleft">
                  <el-button
                    style="margin-right: 10px"
                    type="primary"
                    icon="el-icon-video-play"
                    @click="texttovideo(ppttext[nums].text)"
                    v-show="pptttsflag"
                    size="medium"
                    round
                    >试听</el-button
                  >
                  <el-upload
                    class="upload-demo"
                    :action="url + 'virtual/v1/userPro/resUpload'"
                    :data="upddsobj"
                    :before-upload="befoupload"
                    name="resource"
                    :on-success="successupppt"
                    accept=".wav,.mp3"
                    :show-file-list="false"
                  >
                    <el-button
                      icon="el-icon-upload2"
                      type="primary"
                      round
                      @click="ttspush"
                      size="medium"
                      >上传音频</el-button
                    ><span style="color: red; font-size: 12px">文本禁用</span>
                  </el-upload>
                  <el-button
                    icon="el-icon-video-camera-solid"
                    type="primary"
                    round
                    size="medium"
                    @click="ttspush(), dialogVisibleutles(), startCanvas()"
                    >录制音频</el-button
                  ><span style="color: red; font-size: 12px; margin-top: 10px"
                    >文本禁用</span
                  >
                  <el-button
                    type="primary"
                    icon="el-icon-connection"
                    @click="textDomesScve(2)"
                    v-show="pptttsflag"
                    size="medium"
                    round
                    :loading="saveTextField"
                    >保存文本框</el-button
                  >
                </div>
              </div>
            </div>
            <div>
              <div v-show="pptVideos" style="margin: 50px 0 20px">
                <i class="el-icon-upload2"></i> 第{{ nums + 1 }}页PPT上传的音频
              </div>
              <div>
                <audio
                  v-show="pptVideos"
                  :src="url + pptVideos"
                  ref="videoPlay"
                  controls
                >
                  <source />
                </audio>
              </div>
            </div>
            <div v-show="pptttsflag">
              <div
                id="edits"
                ref="edittow"
                contenteditable
                @click="editClick"
                v-html="ppttext[nums].textdome"
              ></div>
              <div class="bottom">
                <!-- <audio
                  v-show="Videos"
                  :src="url + Videos"
                  ref="videoPlay"
                >
                  <source />
                </audio> -->
                <div class="bottombtn">
                  <span>{{ canvastext }}/300</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- <el-tabs
        type="border-card"
        v-model="activeName"
        :tab-position="tabPosition"
      >
        <el-tab-pane label="PPT列表" name="PPT"
          > -->
      <div class="pptlistas">
        <PPT
          :nums="nums"
          :pptinfoIds="pptinfoIds"
          :pptinfoid="pptinfoid"
          @indeximg="imagelist"
          @imagemax="imagemax"
          :lists="list"
          @pptimg="pptimg"
          @pptupvideo="pptupvideo"
          :isppt="isppt"
          @pptemptas="pptemptas"
          @pptlength="lengthChang"
        />
      </div>
      <!-- </el-tab-pane>
      </el-tabs> -->
    </div>
    <el-dialog title="录音上传" :visible.sync="dialogVisible" width="50%">
      <!-- <h3>录音时长：{{ recorder.duration.toFixed(4) }}</h3>
      <span slot="footer" class="dialog-footer">
        <el-button @click="startvideo">开始录音</el-button>
        <el-button type="primary" @click="startvideostar"
          >暂停录音</el-button
        ><el-button @click="startvideocontinue">结束录音</el-button>
        <el-button type="primary" @click="dialogVisible = false"
          >确 定</el-button
        >
      </span> -->

      <div class="homes" style="margin: 1vw">
        <el-button type="info" @click="startRecorder()" style="margin: 1vw"
          >开始录音</el-button
        >
        <el-button type="info" @click="resumeRecorder()" style="margin: 1vw"
          >继续录音</el-button
        >
        <el-button type="info" @click="pauseRecorder()" style="margin: 1vw"
          >暂停录音</el-button
        >
        <el-button type="info" @click="stopRecorder()" style="margin: 1vw"
          >结束录音</el-button
        >
        <br />
        <el-button type="success" @click="playRecorder()" style="margin: 1vw"
          >录音播放</el-button
        >
        <el-button
          type="success"
          @click="pausePlayRecorder()"
          style="margin: 1vw"
          >暂停录音播放</el-button
        >
        <el-button
          type="success"
          @click="resumePlayRecorder()"
          style="margin: 1vw"
          >恢复录音播放</el-button
        >
        <el-button
          type="success"
          @click="stopPlayRecorder()"
          style="margin: 1vw"
          >停止录音播放</el-button
        >
        <!-- <br />
        <el-button type="info" @click="getRecorder()" style="margin: 1vw"
          >获取录音信息</el-button
        <el-button type="info" @click="downPCM()" style="margin: 1vw"
          >下载PCM</el-button
        >
        <el-button type="info" @click="downWAV()" style="margin: 1vw"
          >下载WAV</el-button
        >
        <el-button type="info" @click="getMp3Data()" style="margin: 1vw"
          >下载MP3</el-button
        >
        <br />
        <el-button type="error" @click="destroyRecorder()" style="margin: 1vw"
          >销毁录音</el-button
        > -->
        <br />

        <el-button type="error" @click="uploadWav()" style="margin: 1vw"
          >上传录音</el-button
        >
        <br />
        <div style="width: 100%; height: 200px; border: 1px solid red">
          <canvas id="canvascideo"></canvas>
          <span style="padding: 0 10%"></span>
          <canvas id="playChart"></canvas>
        </div>
      </div>
    </el-dialog>
    <el-dialog :visible.sync="update" width="40%">
      <el-tabs v-model="matteractiveName">
        <el-tab-pane label="屏幕" name="fullScreen">
          <div class="textureList">
            <div v-for="item in spanList" :key="item.id" class="textures">
              <el-button
                type="primary"
                @click="spanClick(item.value)"
                class="texturebutton"
                >{{ item.value }}</el-button
              >
            </div>
          </div>
        </el-tab-pane>
        <!-- disabled -->
        <el-tab-pane label="贴图" name="texture">
          <div class="textureList">
            <div v-for="item in imgList" :key="item.id" class="texture">
              <el-image
                fit-="contain"
                @click="imgClick(item.path)"
                :src="url + item.path"
                class="textureimg"
              ></el-image>
            </div>
          </div>
        </el-tab-pane>
        <el-tab-pane label="GIF" name="GIF">
          <div class="textureList">
            <div v-for="item in gifList" :key="item.id" class="texture">
              <el-image
                fit-="contain"
                @click="gifClick(item.path)"
                :src="url + item.path"
                class="textureimg"
              ></el-image>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-dialog>
    <el-dialog @opened="opened" :visible.sync="pptlistupdatelist" width="40%">
      <ScenList :backflag="backflag" @backflags="backflags" @pptnum="pptnum" />
    </el-dialog>
  </div>
</template>
<script>
import { domeClassify, screenOk } from "@/utils/SaveFunction";
import {
  userProinfo,
  textToVideo,
  userProupdate,
  videoUpload,
  texturelist,
} from "@/api/virtualhuman";
import {
  jsoncomputer,
  jsisok,
  isttsten,
  jsisokppt,
  pageslist,
  pageslistchils,
  updateup,
} from "@/utils/prijectInfo";
import { Message } from "element-ui";
import { listinfo } from "@/api/menulist";
import UserUp from "@/components/userup.vue";
import HelloWorld from "@/components/HelloWorld.vue";
import Menus from "@/components/menu/MenuS.vue";
import IndexMenus from "@/components/menu/IndexMenu.vue";
import PPT from "./tabs/PPT.vue";
import PPTList from "./tabs/PPTList.vue";
import Scene from "./tabs/scene.vue";
import ScenList from "./tabs/scenelist.vue";
import Timbre from "./tabs/Timbre.vue";
import Recorder from "js-audio-recorder";
import ImageS from "./tabs/ImageS.vue";
import BgMusic from "./tabs/bgMusic.vue";
import $ from "jquery";
const lamejs = require("lamejs");
const recorder = new Recorder({
  sampleBits: 16, // 采样位数，支持 8 或 16，默认是16
  sampleRate: 48000, // 采样率，支持 11025、16000、22050、24000、44100、48000，根据浏览器默认值，我的chrome是48000
  numChannels: 1, // 声道，支持 1 或 2， 默认是1
  // compiling: false,(0.x版本中生效,1.x增加中)  // 是否边录边转换，默认是false
});
export default {
  name: "HomeView",
  components: {
    Menus,
    HelloWorld,
    PPT,
    PPTList,
    UserUp,
    ScenList,
    Scene,
    IndexMenus,
    Timbre,
    ImageS,
    BgMusic,
  },
  data() {
    return {
      saveTextField: false, //保存文本框驾照
      canvastext: 0,
      isppt: false,
      isppts: true,
      buttonsfalse: true, //按钮
      pptlistupdatelist: false, //预览
      content: "",
      spanList: [
        //镜头素材
        {
          id: 11201,
          value: "全屏",
        },
        {
          id: 11202,
          value: "恢复",
        },
      ],
      imgList: [],
      gifList: [],
      matteractiveName: "fullScreen", //素材tab框
      update: false,
      lastEditRange: null,
      edit: "",
      newsContent: "",
      newsBtn: "",
      drawRecordId: null,
      oCanvas: null,
      ctx: null,
      //波浪图-播放
      drawPlayId: null,
      pCanvas: null,
      pCtx: null,
      dialogVisible: false,
      pptVideos: "", //每一页上传的音频
      pptttsflag:
        this.$store.getters["virtualhuman/isttss"](0) === 1 ? false : true, //是否是上传音频的状态隐藏
      upddsobj: {
        projectId: 0, //项目id
        pptSort: 0, //项目顺序
      },
      flagclient:
        this.$store.getters["virtualhuman/getdistinguishability"] === 1
          ? true
          : false,
      pptinfoIds: 0,
      loadingText: "10%",
      liujiu: "",
      url: this.$store.getters["url/urls"],
      Videos: "", //音色
      loading: false, //加载层
      pptinfoid: "", //pptid
      labelPosition: "top", //表单对齐方式
      tabPositions: "left",
      tabPosition: "right",
      backflag: false, //测试是否点了一下背景图
      backwidth: this.$store.getters["virtualhuman/backwid"], //背景图片的宽度
      backheight: this.$store.getters["virtualhuman/backheig"], //背景图片的高度
      backgrouncolor: this.$store.getters["virtualhuman/backgr"], // 背景图片
      user: this.$store.getters["virtualhuman/users"], //从vuex中拿到角色数据
      activeNamethird: "PPTList", //默认渲染第一个
      activeName: "PPT", //默认渲染第一个
      list: [], //传给第一个的表格
      pptindexObj: {}, //传给第二个的单个ppt数据
      nums: 0,
      ppttext: this.$store.getters["virtualhuman/ppttext"],
      image: this.$store.getters["virtualhuman/pptindex"], //从vuex中拿到当前页的ppt图片和文字数据
      x: this.$store.getters["virtualhuman/pptx"], //从vuex中拿到ppt坐标
      y: this.$store.getters["virtualhuman/ppty"], //从vuex中拿到ppt坐标
      w: this.$store.getters["virtualhuman/pptwidth"], //从vuex中拿到ppt坐标
      h: this.$store.getters["virtualhuman/pptheight"], //从vuex中拿到ppt坐标
      w1: this.$store.getters["virtualhuman/userwitdh"], //从vuex中拿到人物坐标
      h1: this.$store.getters["virtualhuman/userheight"], //从vuex中拿到人物坐标
      x1: this.$store.getters["virtualhuman/Xna"], //从vuex中拿到人物坐标
      y1: this.$store.getters["virtualhuman/Yna"], //从vuex中拿到人物坐标
      timbreInfo: {},
      timbresingle: this.$store.getters["virtualhuman/gettonename"], //单个音色
      flagscene: 0, //提醒场景
      input: this.$store.getters["virtualhuman/getjsonname"],
    };
  },
  watch: {
    nums(val) {
      this.image = this.$store.getters["virtualhuman/pptindex"];
      this.canvastext = this.ppttext[val].text.length;
      this.pptttsflag =
        this.$store.getters["virtualhuman/isttss"](this.nums) === 1
          ? false
          : true; //是否是上传音频的状态隐藏
    },
    ppttext: {
      handler: function (val) {
        this.canvastext = val[this.nums].text.length;
      },
      deep: true,
    },
  },
  beforeCreate() {},
  created() {},
  beforeMount() {},
  mounted() {
    this.vidertts();
    this.$store.commit("routerpush/ROUTERALTER", this.$route.query.videoid);
    this.pptlist();
    this.bugbackground();
    this.$nextTick(function () {
      // var time;
      // $("#edits").bind("input propertychange", () => {
      //   clearTimeout(time);
      //   time = setTimeout(() => {
      //     this.textDomesScve(2);
      //   }, 1000);
      // });
      // $("#edit").bind("input propertychange", () => {
      //   clearTimeout(time);
      //   time = setTimeout(() => {
      //     this.textDomesScve(1);
      //   }, 1000);
      // });
      this.routers();
      //修改富文本回车
      this.contenteditables();
      this.texturelistfunction();
    });
  },
  updated: function () {
    this.$nextTick(function () {
      //  仅在整个视图都被重新渲染之后才会运行的代码
      // 由于解除了双向绑定，所以每次有修改都要获取一下ppt输入的文字
      this.ppttext = this.$store.getters["virtualhuman/ppttext"];
      this.timbresingle = this.$store.getters["virtualhuman/gettonename"]; //单个音色
    });
  },
  //组件内路由守卫
  beforeRouteEnter(to, form, next) {
    if (to.query.videoid) {
      next();
      return;
    } else {
      next((vm) => {
        vm.$router.push("/");
        // 通过 `vm` 访问组件实例，说白了就是路由里拿不到this所以这样
        vm.$message.error("非法跳转，请先选择项目");
      });
    }
  },
  methods: {
    texturelistfunction() {
      texturelist({
        pageIndex: 1,
        pageSize: 10,
        textureType: 1,
      }).then((res) => {
        this.imgList = res.data.list;
      });
      texturelist({
        pageIndex: 1,
        pageSize: 10,
        textureType: 2,
      }).then((res) => {
        this.gifList = res.data.list;
      });
    },
    vidertts() {
      Recorder.getPermission().then(
        () => {
          // alert("录音权限已获取");
        },
        (error) => {
          // alert(
          //   `${error.name} : ${error.message}+或未找到录音设备，插入后请刷新页面`
          // );
        }
      );
    },
    pptupok() {
      //上传ppt之后刷新ppt列表
      this.pptlist();
    },
    routers() {
      this.loading = true;
      userProinfo(this.$route.query.videoid).then((res) => {
        if (res.code === 200) {
          this.$store.commit(
            "virtualhuman/JSONPRIONFO",
            JSON.parse(res.data.detail)
          ); //回显项目
          this.$store.commit(
            //设置项目id
            "virtualhuman/JSONPRIONFOUUID",
            this.$route.query.videoid - 0
          );
          //回显
          this.backwidth = this.$store.getters["virtualhuman/backwid"]; //背景图片的宽度
          this.backheight = this.$store.getters["virtualhuman/backheig"]; //背景图片的高度
          this.ppttext = this.$store.getters["virtualhuman/ppttext"];
          this.image = this.$store.getters["virtualhuman/pptindex"]; //从vuex中拿到当前页的ppt图片和文字数据

          this.y = this.$store.getters["virtualhuman/ppty"]; //从vuex中拿到ppt坐标
          this.x = this.$store.getters["virtualhuman/pptx"]; //从vuex中拿到ppt坐标
          this.w = this.$store.getters["virtualhuman/pptwidth"]; //从vuex中拿到ppt坐标
          this.h = this.$store.getters["virtualhuman/pptheight"]; //从vuex中拿到ppt坐标
          this.h1 = this.$store.getters["virtualhuman/userheight"]; //从vuex中拿到人物坐标
          this.w1 = this.$store.getters["virtualhuman/userwitdh"]; //从vuex中拿到人物坐标
          this.x1 = this.$store.getters["virtualhuman/Xna"]; //从vuex中拿到人物坐标
          this.y1 = this.$store.getters["virtualhuman/Yna"]; //从vuex中拿到人物坐标
          this.backgrouncolor = this.$store.getters["virtualhuman/backgr"]; // 背景图片
          this.pptttsflag =
            this.$store.getters["virtualhuman/isttss"](this.nums) === 1
              ? false
              : true; //判断是否音频还是文字
          this.upddsobj.projectId =
            this.$store.getters["virtualhuman/pagesuuids"];
          //判断到底是什么类型
          this.flagclient =
            this.$store.getters["virtualhuman/getdistinguishability"] === 1
              ? true
              : false;
          this.bugbackground();
          this.pptId(); //ppt回显
          this.flagscene =
            this.$store.getters["virtualhuman/getdistinguishability"];
          this.pptVideos = this.image[this.nums].tts;
          this.input = this.$store.getters["virtualhuman/getjsonname"];
          this.user = this.$store.getters["virtualhuman/users"]; //从vuex中拿到角色数据
          this.loading = false;
        } else {
          this.$message({
            message: res.msg,
            type: "error",
          });
          this.loading = false;
        }
      });
    },
    contenteditables() {
      // 修改富文本回车
      $("#edit").keydown(function (e) {
        if (e.keyCode === 13) {
          document.execCommand("insertHTML", false, "<br><br>");
          return false;
        }
      });
      $("#edits").keydown(function (e) {
        if (e.keyCode === 13) {
          document.execCommand("insertHTML", false, "<br><br>");
          return false;
        }
      });
    },
    pptId() {
      //判断pptid回显
      if (this.$store.getters["virtualhuman/pptid"] !== 0) {
        this.pptinfoIds = this.$store.getters["virtualhuman/pptid"];
      }
    },
    //处理空ppt
    emptypptimg() {
      this.nums = 0;
      this.pptinfoid = "0";
      this.isppts = false;
      this.$store.commit("virtualhuman/PPTTEXTEMPTY");
      this.isppt = true;
      this.image = this.$store.getters["virtualhuman/pptindex"];
    },
    //处理空取消触发清空列表
    pptemptas() {
      this.isppt = false;
    },
    //选择PPT后处理
    pptimg(val) {
      this.pptinfoid = val;
      this.isppts = true;
    },
    userlist(val) {
      //选择人物后的数据
      //截取一下音色好页面渲染
      this.timbreInfo = val.timbreInfo;
      this.$store.commit("virtualhuman/USERIMAGES", val);
      this.user = this.$store.getters["virtualhuman/users"];
    },
    lengthChang() {
      this.nums--;
    },
    pptlist(index) {
      // 请求ppt列表
      listinfo({ pageIndex: index, pageSize: 6, type: 2 }).then((res) => {
        this.list = res.data;
      });
    },
    imagemax(val) {
      //点击PPT后获取到详情后储存到vuex里面后渲染第一张ppt到页面上
      this.$store.commit("virtualhuman/PPTMAX", val);
      this.nums = 0;
      this.image = this.$store.getters["virtualhuman/pptindex"];
    },
    imagelist(val, item) {
      //点了哪个PPT
      this.$nextTick(() => {
        this.$store.commit("virtualhuman/PPTNUMBER", {
          item,
          val,
        });
        this.nums = item;
        this.image = this.$store.getters["virtualhuman/pptindex"];
        this.pptVideos = this.image[this.nums].tts;
      });
    },
    onResize(left, top, width, height) {
      //ppt调整宽高大小
      this.$store.commit("virtualhuman/SETPPTWIDTH", {
        pptWidth: width,
        pptHeight: height,
        pptX: left,
        pptY: top,
      });
    },
    onDrag(left, top) {
      this.$store.commit("virtualhuman/SETHEIGHT", {
        //ppt移动
        pptX: left,
        pptY: top,
      });
    },
    //人物移动x,y
    onDraguser(left, top) {
      this.$store.commit("virtualhuman/DRAGUSER", { x: left, y: top }); //让大家共用一个人物坐标
    },
    //人物调整大小
    usersize(left, top, width, height) {
      this.$store.commit("virtualhuman/COORDINATE", {
        x: left,
        y: top,
        width,
        height,
      }); //让大家共用一个人物坐标
    },
    //调整jpg大小
    onResizejpg(index, left, top, width, height) {
      let jpg = this.ppttext[this.nums].textureList[index];
      jpg.height = height;
      jpg.x = left;
      jpg.y = top;
      jpg.width = width;
      this.$store.commit("virtualhuman/DRAJPG", {
        num: this.nums,
        index,
        left,
        top,
        width,
        height,
      });
    },
    //移动jpg大小
    onDragjpg(index, left, top) {
      let jpg = this.ppttext[this.nums].textureList[index];
      jpg.x = left;
      jpg.y = top;
      this.$store.commit("virtualhuman/RESIZJPG", {
        num: this.nums,
        index,
        left,
        top,
      });
    },
    backgroun(val) {
      //选中的背景图
      this.$store.commit("virtualhuman/BACKGROUNDS", val);
      const bag = this.$refs.carvas; //获取dom节点
      const baga = this.$refs.carvasa; //获取dom节点
      this.backgrouncolor = this.$store.getters["virtualhuman/backgr"];
      bag.style.backgroundImage = `url(${this.url + this.backgrouncolor})`;
      baga.style.backgroundImage = `url(${this.url + this.backgrouncolor})`;
      this.backflag = true; //让背景也确认点了
    },
    backflags(val) {
      this.backflag = val;
    },
    backwidheig() {
      const bag = this.$refs.carvas; //获取dom节点
      const baga = this.$refs.carvasa; //获取dom节点
      // bag.style.width = `${this.$store.getters["virtualhuman/backwid"]}px`;
      // bag.style.height = `${this.$store.getters["virtualhuman/backheig"]}px`;
      bag.style.backgroundImage = `url(${this.url + this.backgrouncolor})`;
      baga.style.backgroundImage = `url(${this.url + this.backgrouncolor})`;
    },
    pptnum(num) {
      //精华：点了哪个menu就单传过menu数字过来，这样就可以实验对应页面拿取对应页面的数据了
      this.image = this.$store.getters["virtualhuman/pptindex"];
      this.nums = num;
    },
    chang(text) {
      //设置表单变化立马保存到对应ppt一次
      this.$store.commit("virtualhuman/PPTTEXT", { text, num: this.nums });
    },
    //解决bug背景渲染问题
    bugbackground() {
      const bag = this.$refs.carvas; //获取dom节点
      const baga = this.$refs.carvasa; //获取dom节点
      this.backgrouncolor = this.$store.getters["virtualhuman/backgr"];
      bag.style.backgroundImage = `url(${this.url + this.backgrouncolor})`;
      baga.style.backgroundImage = `url(${this.url + this.backgrouncolor})`;
      this.backflag = true; //让背景也确认点了
    },
    //音色确认
    timbersingle(val, id) {
      this.timbresingle = val.show_name;
      this.$store.commit("virtualhuman/TIMBER", {
        name: val.name,
        tonename: val.show_name,
        voiceId: id,
      });
    },
    //听单个音频
    texttovideo(val) {
      if (!this.$store.getters["virtualhuman/textvideouser"]) {
        this.$message.error("音色未选择");
      } else if (!val) {
        this.$message.error("文本未保存或无文字");
      } else {
        this.loading = true;
        this.loadingText = "50%";
        textToVideo({
          uuid: this.$route.query.videoid - 0,
          sampleRate: 1600,
          // speechRate:500,
          voice: this.$store.getters["virtualhuman/textvideouser"],
          textList: [val],
          opt: 1,
        }).then((res) => {
          this.loadingText = "75%";
          if (res.code === 200) {
            this.$message({
              message: res.msg,
              type: "success",
            });
            this.Videos = res.data[0].Video + "?" + +new Date();
            // this.$refs.videoPlay.src =
            //   this.url + res.data[0].Video + `?${+new Date()}`;
            this.loadingText = "100%";
          } else {
            this.$message({
              message: res.msg,
              type: "error",
            });
          }
          this.loading = false;
        });
      }
    },
    //上传ppt中的video时或者删除单页PPT立马保存一次json
    pptupvideo() {
      this.conserve();
    },
    //保存json
    conserve() {
      this.loading = true;
      var json = this.$store.getters["virtualhuman/json"];
      userProupdate({
        projectId: json.uuid - 0,
        userProjectInfo: json,
        original: 1,
      })
        .then((res) => {
          if (res.code === 200) {
            this.$message({
              message: res.msg,
              type: "success",
            });
          } else {
            this.$message({
              message: res.msg,
              type: "error",
            });
          }
          this.loading = false;
        })
        .catch(() => {
          this.loading = false;
        });
    },
    //切换16：9场景
    clientside() {
      this.flagclient = true;
      this.$store.commit("virtualhuman/SETCLIENTSIDE");
      const bag = this.$refs.carvas; //获取dom节点
      const baga = this.$refs.carvasa; //获取dom节点
      this.$store.commit("virtualhuman/BACKGROUNDS", {
        path: "",
        name: "",
        type: 1,
      });
      bag.style.backgroundImage = `url(${this.url})`;
      baga.style.backgroundImage = `url(${this.url})`;
      this.$store.commit("virtualhuman/XCOORDINATE", 0); //让大家共用一个人物坐标
      this.$store.commit("virtualhuman/YCOORDINATE", 100); //让大家共用一个人物坐标
      this.$store.commit("virtualhuman/WIDTHCOORDINATE", 225); //让大家共用一个人物坐标
      this.$store.commit("virtualhuman/HEIGHTCOORDINATE", 300); //让大家共用一个人物坐标
      this.$store.commit("virtualhuman/SETHEIGHT", {
        //ppt移动
        pptX: 1,
        pptY: 1,
      });
      this.x1 = 10;
      this.y1 = 10;
      this.w1 = 10; //从vuex中拿到人物坐标
      this.h1 = 10; //从vuex中拿到人物坐标
      setTimeout(() => {
        this.x = this.$store.getters["virtualhuman/pptx"]; //从vuex中拿到ppt坐标
        this.y = this.$store.getters["virtualhuman/ppty"]; //从vuex中拿到ppt坐标
        this.w = this.$store.getters["virtualhuman/pptwidth"]; //从vuex中拿到ppt坐标
        this.h = this.$store.getters["virtualhuman/pptheight"]; //从vuex中拿到ppt坐标
        this.x1 = 0;
        this.y1 = 100;
        this.w1 = 225; //从vuex中拿到人物坐标
        this.h1 = 300; //从vuex中拿到人物坐标
      }, 500);
    },
    //切换9：16场景
    mobileclient() {
      this.flagclient = false;
      const bag = this.$refs.carvas; //获取dom节点
      const baga = this.$refs.carvasa; //获取dom节点
      this.$store.commit("virtualhuman/CLIENTSIDESET");
      this.$store.commit("virtualhuman/BACKGROUNDS", {
        path: "",
        name: "",
        type: 1,
      });
      bag.style.backgroundImage = `url(${this.url})`;
      baga.style.backgroundImage = `url(${this.url})`;
      this.$store.commit("virtualhuman/XCOORDINATE", 0); //让大家共用一个人物坐标
      this.$store.commit("virtualhuman/YCOORDINATE", 100); //让大家共用一个人物坐标
      this.$store.commit("virtualhuman/WIDTHCOORDINATE", 225); //让大家共用一个人物坐标
      this.$store.commit("virtualhuman/HEIGHTCOORDINATE", 300); //让大家共用一个人物坐标
      this.$store.commit("virtualhuman/SETHEIGHT", {
        //ppt移动
        pptX: 1,
        pptY: 1,
      });
      this.w1 = 10; //从vuex中拿到人物坐标
      this.h1 = 10; //从vuex中拿到人物坐标
      setTimeout(() => {
        this.x = this.$store.getters["virtualhuman/pptx"]; //从vuex中拿到ppt坐标
        this.y = this.$store.getters["virtualhuman/ppty"]; //从vuex中拿到ppt坐标
        this.w = this.$store.getters["virtualhuman/pptwidth"]; //从vuex中拿到ppt坐标
        this.h = this.$store.getters["virtualhuman/pptheight"]; //从vuex中拿到ppt坐标
        this.x1 = 0;
        this.y1 = 100;
        this.w1 = 225; //从vuex中拿到人物坐标
        this.h1 = 300; //从vuex中拿到人物坐标
      }, 500);
    },
    ttspush() {
      //打开上传音频
      this.$store.commit("virtualhuman/ISALTERTTS", this.nums);
      this.pptttsflag =
        this.$store.getters["virtualhuman/isttss"](this.nums) === 1
          ? false
          : true; //是否是上传音频的状态隐藏
      return false;
    },
    removetts() {
      //恢复成文本输入
      this.$confirm("此操作会将上传的音频文件删除, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.$message({
            type: "success",
            message: "切换成功!",
          });
          this.$store.commit("virtualhuman/REMOVETTS", this.nums);
          this.pptttsflag =
            this.$store.getters["virtualhuman/isttss"](this.nums) === 1
              ? false
              : true; //是否是上传音频的状态隐藏
          this.pptVideos = this.image[this.nums].tts;
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消",
          });
        });
    },
    //文件上传之前的钩子
    befoupload(file) {
      var size = file.size / 1024 / 1024 / 1024 < 1;
      if (size) {
        if (file.type === "audio/wav" || file.type === "audio/mpeg") {
          this.pptinfoIds = this.$store.getters["virtualhuman/pptid"];
          if (this.isppts) {
            if (this.pptinfoIds !== 0) {
              this.upddsobj.pptSort = this.nums + 1;
              return true;
            } else {
              this.$message({
                type: "error",
                message: "PPT未选择已取消",
              });
              return false;
            }
          } else {
            this.upddsobj.pptSort = this.nums + 1;
            return true;
          }
        } else {
          this.$message({
            type: "error",
            message: `错误：必须上传格式为wav文件，您上传格式为${file.type}`,
          });
          return false;
        }
      } else {
        this.$message({
          type: "error",
          message: `错误：上传文件大小不可大于1G`,
        });
        return false;
      }
    },
    successupppt(response) {
      if (response.code === 200) {
        let obj = { url: response.data.path, nums: this.nums };
        this.$store.commit("virtualhuman/PPTPAGASNUM", obj);
        this.pptVideos = response.data.path + "?" + +new Date();
      } else {
        this.$message({
          type: "error",
          message: response.msg,
        });
      }
    },
    //合成视频
    compound() {
      let json = JSON.parse(
        JSON.stringify(this.$store.getters["virtualhuman/json"])
      );
      if (jsisokppt(json)) {
        if (isttsten(json.ppt.pages)) {
          //分辨率 1是16：9，2是9：16
          this.loading = true;
          this.loadingText = "10%";
          if (json.distinguishability === 1) {
            json = jsoncomputer(json, 2);
          } else if (json.distinguishability === 2) {
            json = jsoncomputer(json, 2.47);
          }
          this.loadingText = "30%";
          pageslist(json, this.loadingText)
            .then((res) => {
              this.loadingText = "60%";
              json = res;
              pageslistchils(json)
                .then((ress) => {
                  this.loadingText = "80%";
                  json = ress;
                  //提交json
                  updateup(json)
                    .then((resss) => {
                      Message.success(resss.msg);
                      this.loadingText = "100%";
                      this.$store.commit("routerpush/ROUTERALTER", "");
                      this.loading = false;
                      this.$store.commit("virtualhuman/REMOVEJSON");
                      this.$router.push("/");
                    })
                    .catch((err) => {
                      Message.error(err.msg);
                      this.loading = false;
                    });
                })
                .catch((err) => {
                  Message.error(err.msg);
                  this.loading = false;
                });
            })
            .catch((err) => {
              Message.error(err.msg);
              this.loading = false;
            });
        }
      }
    },
    //合成空ppt视频
    emptycompound() {
      let json = JSON.parse(
        JSON.stringify(this.$store.getters["virtualhuman/json"])
      );
      if (jsisok(json)) {
        if (isttsten(json.ppt.pages)) {
          //是否为手机 1是16：9，2是9：16
          if (json.distinguishability === 1) {
            //计算人物坐标
            json = jsoncomputer(json, 2);
          } else {
            json = jsoncomputer(json, 2.47);
          }
          this.loading = true;
          this.loadingText = "25%";
          pageslist(json)
            .then((res) => {
              json = res;
              this.loadingText = "75%";
              updateup(json)
                .then((ress) => {
                  Message.success(ress.msg);
                  this.loadingText = "100%";
                  this.$store.commit("routerpush/ROUTERALTER", "");
                  this.loading = false;
                  this.$store.commit("virtualhuman/REMOVEJSON");
                  this.$router.push("/");
                })
                .catch((err) => {
                  Message.error(err.msg);
                  this.loading = false;
                });
            })
            .catch((err) => {
              Message.error(err.msg);
              this.loading = false;
            });
        }
      }
    },
    dialogVisibleutles() {
      this.dialogVisible = true;
    },

    interpositionnode() {
      //打开插入元素并且获取光标位置
      this.update = true;
      let selection = getSelection();
      // 设置最后光标对象
      this.lastEditRange = selection.getRangeAt(0);
    },
    editClick() {
      // 获取选定对象
      let selection = getSelection();
      // 设置最后光标对象
      this.lastEditRange = selection.getRangeAt(0);
      this.buttonsfalse = false;
    },
    //插入全屏
    spanClick(val) {
      var selection = getSelection();
      // 如果保存的有上次的光标对象
      if (this.lastEditRange) {
        // && this.lastEditRange.endContainer.parentElement.id==="edit"|| this.lastEditRange.endContainer.parentElement.id==="edis"
        // 清除所有选区
        selection.removeAllRanges();
        // 添加最后光标还原之前的状态
        selection.addRange(this.lastEditRange);
        // 获取光标对象
        var range = selection.getRangeAt(0);
        // 获取光标对象的范围界定对象，一般就是textNode对象
        var textNode = range.startContainer;
        // // 获取光标位置
        // var rangeStartOffset = range.startOffset;
        //   console.log(rangeStartOffset);
        var a = range.commonAncestorContainer;
        let el = document.createElement("div");
        let span = document.createElement("span");
        span.style.cssText =
          "display: inline-block;font-size: 14px;border-radius: 4px;color: #0590DF;background-color: rgba(5, 144, 223, 0.0980392156862745);width:50px;line-height:20px;height:20px;text-align:center";
        span.setAttribute("contenteditable", "false");
        el.appendChild(span);
        span.appendChild(document.createTextNode("\u200b")); // 非法字符错误：零度空间（空格）
        this.spanList.map((item) => {
          if (item.value === val) {
            return (this.content = item.value);
          }
        });
        span.innerHTML = "@" + this.content ? "@" + this.content : "";
        var frag = document.createDocumentFragment(),
          node,
          lastNode;
        while ((node = el.firstChild)) {
          lastNode = frag.appendChild(span);
        }
        // 在光标位置处插入新的表情内容
        range.insertNode(frag);
        // 添加了新内容，将光标移动到新的位置
        if (lastNode) {
          range = range.cloneRange();
          range.setStartAfter(lastNode);
          range.collapse(true);
          selection?.removeAllRanges();
          selection?.addRange(range);
        }
        this.update = false;
        this.buttonsfalse = true;
        // let json = this.$store.getters["virtualhuman/json"];
        //   this.textDomesScve(json.distinguishability);
        // 记录最后光标对象
        this.lastEditRange = selection.getRangeAt(0);
      } else {
        return;
      }
    },
    //插入贴图
    imgClick(val) {
      var selection = getSelection();
      // 如果保存的有上次的光标对象
      if (this.lastEditRange) {
        // && this.lastEditRange.endContainer.parentElement.id==="edit"|| this.lastEditRange.endContainer.parentElement.id==="edis"
        // 清除所有选区
        selection.removeAllRanges();
        // 添加最后光标还原之前的状态
        selection.addRange(this.lastEditRange);

        // 获取光标对象
        var range = selection.getRangeAt(0);

        // 获取光标对象的范围界定对象，一般就是textNode对象
        var textNode = range.startContainer;
        // // 获取光标位置
        // var rangeStartOffset = range.startOffset;
        //   console.log(rangeStartOffset);
        var a = range.commonAncestorContainer;
        let el = document.createElement("div");
        let span = document.createElement("i");
        span.style.cssText =
          "display: inline-block;font-size: 14px;border-radius: 4px;color: #0590DF;background-color: rgba(5, 144, 223, 0.0980392156862745);width:55px;line-height:20px;height:20px;text-align:center";
        span.setAttribute("contenteditable", "false");
        el.appendChild(span);
        span.appendChild(document.createTextNode("\u200b")); // 非法字符错误：零度空间（空格）
        this.imgList.map((item) => {
          if (item.path === val) {
            return (this.content = item.textureId);
          }
        });
        span.innerHTML = "@" + this.content ? "@" + this.content : "";
        var frag = document.createDocumentFragment(),
          node,
          lastNode;
        while ((node = el.firstChild)) {
          lastNode = frag.appendChild(span);
        }
        // 在光标位置处插入新的表情内容
        range.insertNode(frag);
        // 添加了新内容，将光标移动到新的位置
        if (lastNode) {
          range = range.cloneRange();
          range.setStartAfter(lastNode);
          range.collapse(true);
          selection?.removeAllRanges();
          selection?.addRange(range);
        }
        this.update = false;
        this.buttonsfalse = true;
        // let json = this.$store.getters["virtualhuman/json"];
        //   this.textDomesScve(json.distinguishability);
        // 记录最后光标对象
        this.lastEditRange = selection.getRangeAt(0);
      } else {
        return;
      }
    },
    gifClick(val) {
      var selection = getSelection();
      // 如果保存的有上次的光标对象
      if (this.lastEditRange) {
        // && this.lastEditRange.endContainer.parentElement.id==="edit"|| this.lastEditRange.endContainer.parentElement.id==="edis"
        // 清除所有选区
        selection.removeAllRanges();
        // 添加最后光标还原之前的状态
        selection.addRange(this.lastEditRange);

        // 获取光标对象
        var range = selection.getRangeAt(0);

        // 获取光标对象的范围界定对象，一般就是textNode对象
        var textNode = range.startContainer;
        // // 获取光标位置
        // var rangeStartOffset = range.startOffset;
        //   console.log(rangeStartOffset);
        var a = range.commonAncestorContainer;
        let el = document.createElement("div");
        let span = document.createElement("i");
        span.style.cssText =
          "display: inline-block;font-size: 14px;border-radius: 4px;color: #0590DF;background-color: rgba(5, 144, 223, 0.0980392156862745);width:55px;line-height:20px;height:20px;text-align:center";
        span.setAttribute("contenteditable", "false");
        el.appendChild(span);
        span.appendChild(document.createTextNode("\u200b")); // 非法字符错误：零度空间（空格）
        this.gifList.map((item) => {
          if (item.path === val) {
            return (this.content = item.textureId);
          }
        });
        span.innerHTML = "@" + this.content ? "@" + this.content : "";
        var frag = document.createDocumentFragment(),
          node,
          lastNode;
        while ((node = el.firstChild)) {
          lastNode = frag.appendChild(span);
        }
        // 在光标位置处插入新的表情内容
        range.insertNode(frag);
        // 添加了新内容，将光标移动到新的位置
        if (lastNode) {
          range = range.cloneRange();
          range.setStartAfter(lastNode);
          range.collapse(true);
          selection?.removeAllRanges();
          selection?.addRange(range);
        }
        this.update = false;
        this.buttonsfalse = true;
        // 记录最后光标对象
        this.lastEditRange = selection.getRangeAt(0);
      } else {
        return;
      }
    },
    //1是16:9 2是9：16保存文本框
    textDomesScve(judge) {
      this.saveTextField = true;
      let textdome;
      if (judge == 1) {
        textdome = this.$refs.editone;
      } else if (judge == 2) {
        textdome = this.$refs.edittow;
      }
      let Nodes = textdome.childNodes;
      let HTMLText = textdome.innerHTML;
      let { text, screen, jpg } = domeClassify(Nodes);
      if (screenOk(text, screen)) {
        //正常保存
        this.$store.commit("virtualhuman/PPTTEXT", {
          text,
          num: this.nums,
          HTMLText,
          screen,
          jpg,
        });
        //处理全屏输入以及插图
        this.$store.commit("virtualhuman/PPTTEXTDIVIDE", this.nums);
        let pptpage = this.$store.getters["virtualhuman/ppttext"];

        this.$store
          .dispatch("virtualhuman/pptindeximg", {
            imgarr: pptpage[this.nums],
            indexs: this.nums,
          })
          .then(() => {
            this.saveTextField = false;
          });
      } else {
        this.saveTextField = false;
      }
    },
    //预览
    pptlistarrsay() {
      this.pptlistupdatelist = true;
    },
    opened() {
      this.backflag = true;
    },
    refercanto() {
      this.liujiu = "width:540px;height:960px";
      this.$store.commit("virtualhuman/BAKWID", { wid: 540, heg: 960 });
      var json = this.$store.getters["virtualhuman/json"];
      userProupdate({
        projectId: json.uuid - 0,
        userProjectInfo: json,
      }).then((res) => {
        // this.$router.go(0)
      });
    },
    canreferto() {
      this.liujiu = "width:960px;height:540px";
      this.$store.commit("virtualhuman/BAKWID", { wid: 960, heg: 540 });
      var json = this.$store.getters["virtualhuman/json"];
      userProupdate({
        projectId: json.uuid - 0,
        userProjectInfo: json,
      }).then((res) => {
        // this.$router.go(0)
      });
    },
    //     startvideo(){
    // this.recorder.start(); // 开始录音
    //     },
    //     startvideostar(){
    // //  this.recorder.stop();//停止录音
    //     this.recorder.pause();
    //     },
    //     startvideocontinue(){
    //       this.recorder.resume()
    //     },
    /**
     * 波浪图配置
     * */
    startCanvas() {
      //录音波浪
      this.$nextTick(function () {
        this.oCanvas = document.getElementById("canvascideo");
        this.ctx = this.oCanvas.getContext("2d");
        //播放波浪
        this.pCanvas = document.getElementById("playChart");
        this.pCtx = this.pCanvas.getContext("2d");
      });
    },

    /**
     *  录音的具体操作功能
     * */
    // 开始录音
    startRecorder() {
      recorder.start().then(
        () => {
          this.drawRecord(); //开始绘制图片
        },
        (error) => {
          // 出错了
          this.$message.error(
            `${error.name} : ${error.message}未找到录音设备，如已插入，请保存后刷新`
          );
        }
      );
    },
    // 继续录音
    resumeRecorder() {
      recorder.resume();
      this.drawRecord(); //开始绘制图片
    },
    // 暂停录音
    pauseRecorder() {
      recorder.pause();
      this.drawRecordId && cancelAnimationFrame(this.drawRecordId);
      this.drawRecordId = null;
    },
    // 结束录音
    stopRecorder() {
      recorder.stop();
      this.drawRecordId && cancelAnimationFrame(this.drawRecordId);
      this.drawRecordId = null;
    },
    // 录音播放
    playRecorder() {
      recorder.play();
      this.drawPlay(); //绘制波浪图
    },
    // 暂停录音播放
    pausePlayRecorder() {
      recorder.pausePlay();
    },
    // 恢复录音播放
    resumePlayRecorder() {
      recorder.resumePlay();
      this.drawPlay(); //绘制波浪图
    },
    // 停止录音播放
    stopPlayRecorder() {
      recorder.stopPlay();
    },
    // 销毁录音
    destroyRecorder() {
      recorder.destroy().then(function () {
        recorder = null;
        this.drawRecordId && cancelAnimationFrame(this.drawRecordId);
        this.drawRecordId = null;
      });
    },
    /**
     *  获取录音文件
     * */
    getRecorder() {
      let toltime = recorder.duration; //录音总时长
      let fileSize = recorder.fileSize; //录音总大小

      //录音结束，获取取录音数据
      let PCMBlob = recorder.getPCMBlob(); //获取 PCM 数据
      let wav = recorder.getWAVBlob(); //获取 WAV 数据

      let channel = recorder.getChannelData(); //获取左声道和右声道音频数据

      // console.log(toltime);
      // console.log(fileSize);
      // console.log(PCMBlob);
      // console.log(wav);
      // console.log(channel);
      // console.log(recorder);
    },
    /**
     *  下载录音文件
     * */
    //下载pcm
    downPCM() {
      //这里传参进去的时文件名
      recorder.downloadPCM("新文件");
    },
    //下载wav
    downWAV() {
      //这里传参进去的时文件名
      recorder.downloadWAV("新文件");
    },
    /**
     * 文件格式转换 wav-map3
     * */
    getMp3Data() {
      const mp3Blob = this.convertToMp3(recorder.getWAV());
      recorder.download(mp3Blob, "recorder", "mp3");
    },
    blobToFile(theBlob, fileName) {
      //将blob转换为file
      let file = new File([theBlob], fileName, {
        type: theBlob.type.split("/")[1],
        lastModified: Date.now(),
      });
      return file;
    },
    convertToMp3(wavDataView) {
      // 获取wav头信息
      const wav = lamejs.WavHeader.readHeader(wavDataView); // 此处其实可以不用去读wav头信息，毕竟有对应的config配置
      const { channels, sampleRate } = wav;
      const mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);
      // 获取左右通道数据
      const result = recorder.getChannelData();
      const buffer = [];

      const leftData =
        result.left &&
        new Int16Array(result.left.buffer, 0, result.left.byteLength / 2);
      const rightData =
        result.right &&
        new Int16Array(result.right.buffer, 0, result.right.byteLength / 2);
      const remaining = leftData.length + (rightData ? rightData.length : 0);

      const maxSamples = 1152;
      for (let i = 0; i < remaining; i += maxSamples) {
        const left = leftData.subarray(i, i + maxSamples);
        let right = null;
        let mp3buf = null;

        if (channels === 2) {
          right = rightData.subarray(i, i + maxSamples);
          mp3buf = mp3enc.encodeBuffer(left, right);
        } else {
          mp3buf = mp3enc.encodeBuffer(left);
        }

        if (mp3buf.length > 0) {
          buffer.push(mp3buf);
        }
      }

      const enc = mp3enc.flush();

      if (enc.length > 0) {
        buffer.push(enc);
      }

      return new Blob(buffer, { type: "audio/mp3" });
    },

    /**
     * 绘制波浪图-录音
     * */
    drawRecord() {
      // 用requestAnimationFrame稳定60fps绘制
      this.drawRecordId = requestAnimationFrame(this.drawRecord);

      // 实时获取音频大小数据
      let dataArray = recorder.getRecordAnalyseData(),
        bufferLength = dataArray.length;

      // 填充背景色
      this.ctx.fillStyle = "rgb(200, 200, 200)";
      this.ctx.fillRect(0, 0, this.oCanvas.width, this.oCanvas.height);

      // 设定波形绘制颜色
      this.ctx.lineWidth = 2;
      this.ctx.strokeStyle = "rgb(0, 0, 0)";

      this.ctx.beginPath();

      var sliceWidth = (this.oCanvas.width * 1.0) / bufferLength, // 一个点占多少位置，共有bufferLength个点要绘制
        x = 0; // 绘制点的x轴位置

      for (var i = 0; i < bufferLength; i++) {
        var v = dataArray[i] / 128.0;
        var y = (v * this.oCanvas.height) / 2;

        if (i === 0) {
          // 第一个点
          this.ctx.moveTo(x, y);
        } else {
          // 剩余的点
          this.ctx.lineTo(x, y);
        }
        // 依次平移，绘制所有点
        x += sliceWidth;
      }

      this.ctx.lineTo(this.oCanvas.width, this.oCanvas.height / 2);
      this.ctx.stroke();
    },
    /**
     * 绘制波浪图-播放
     * */
    drawPlay() {
      // 用requestAnimationFrame稳定60fps绘制
      this.drawPlayId = requestAnimationFrame(this.drawPlay);

      // 实时获取音频大小数据
      let dataArray = recorder.getPlayAnalyseData(),
        bufferLength = dataArray.length;

      // 填充背景色
      this.pCtx.fillStyle = "rgb(200, 200, 200)";
      this.pCtx.fillRect(0, 0, this.pCanvas.width, this.pCanvas.height);

      // 设定波形绘制颜色
      this.pCtx.lineWidth = 2;
      this.pCtx.strokeStyle = "rgb(0, 0, 0)";

      this.pCtx.beginPath();

      var sliceWidth = (this.pCanvas.width * 1.0) / bufferLength, // 一个点占多少位置，共有bufferLength个点要绘制
        x = 0; // 绘制点的x轴位置

      for (var i = 0; i < bufferLength; i++) {
        var v = dataArray[i] / 128.0;
        var y = (v * this.pCanvas.height) / 2;

        if (i === 0) {
          // 第一个点
          this.pCtx.moveTo(x, y);
        } else {
          // 剩余的点
          this.pCtx.lineTo(x, y);
        }
        // 依次平移，绘制所有点
        x += sliceWidth;
      }

      this.pCtx.lineTo(this.pCanvas.width, this.pCanvas.height / 2);
      this.pCtx.stroke();
    },
    uploadWav() {
      //录制的音频上传
      this.pptinfoIds = this.$store.getters["virtualhuman/pptid"];
      //文件上传之前的钩子
      if (this.pptinfoIds !== 0) {
        var wavBlob = recorder.getWAVBlob();
        var formData = new FormData();
        //  const newbolb = new Blob([wavBlob], { type: 'audio/wav' })
        // let file = this.blobToFile(recorder.getWAVBlob(), "1.wav");
        const fileOfBlob = new File([wavBlob], new Date().getTime() + ".wav");
        formData.append("resource", fileOfBlob);
        formData.append("pptSort", this.nums + 1);
        formData.append(
          "projectId",
          this.$store.getters["virtualhuman/pagesuuids"]
        );
        videoUpload(formData)
          .then((res) => {
            if (res.code === 200) {
              let obj = { url: res.data, nums: this.nums };
              this.$store.commit("virtualhuman/PPTPAGASNUM", obj);
              this.pptVideos = res.data + "?" + +new Date();
              this.$message({
                message: res.msg,
                type: "success",
              });
              recorder.destroy().then(function () {
                recorder = null;
                this.drawRecordId && cancelAnimationFrame(this.drawRecordId);
                this.drawRecordId = null;
              });
              this.dialogVisible = false;
            } else {
              this.$message({
                type: "error",
                message: res.msg,
              });
              this.dialogVisible = false;
            }
          })
          .catch((err) => {
            this.dialogVisible = false;
          });
      } else {
        this.$message({
          type: "error",
          message: "PPT未选择已取消上传",
        });
      }
    },
  },
};
</script>
<style lang="scss" scoped>
#edit {
  height: 15vh;
  border: 1px solid #ccc;
  border-radius: 10px;
  text-align: left;
  max-width: 49vw;
  overflow-y: auto;
  box-sizing: border-box;
}

#edits {
  height: 15vh;
  border: 1px solid #ccc;
  border-radius: 10px;
  text-align: left;
  overflow-y: auto;
  max-width: 49vw;
  position: relative;
  box-sizing: border-box;
}
.textureList {
  display: flex;
  flex-wrap: wrap;
  padding: 10px;
  box-sizing: border-box;
  height: 40vh;
  .texture {
    margin-left: 4%;
    width: 110px;
    height: 110px;
    padding: 10px;
    &:hover {
      cursor: pointer;
      background-color: #8ac0f7;
    }
    .textureimg {
      width: 100%;
      height: 100%;
    }
  }
  .textures {
    margin-left: 4%;
    width: 45%;
    height: 50%;
    .texturebutton {
      width: 100%;
      height: 100%;
    }
  }
}
.loader {
  transform: translate(-50%, -50%);
  position: absolute;
  top: 50%;
  left: 50%;
}

.tops {
  background-color: #000;
  height: 100%;
  overflow-y: auto;
}

.home {
  padding-top: 5px;
  display: flex;
  justify-content: space-between;
  height: 90vh;
  background-color: #000;

  .tabssab {
    width: 22%;
    height: 100%;
    overflow: hidden;
    background-color: #26263c;
    border: none;
    box-shadow: 2px 2px 2px 1px;
  }
}

.bordercavas {
  margin: 0 auto;
}
.carvas {
  position: relative;
  border: 2px solid #222;
  background-color: #000;
  z-index: 0;
  width: 960px;
  height: 540px;
  background-size: 100% 100%;
  margin-top: 1px;
  .imges {
    width: 100%;
    height: 100%;
  }
}

.carvasflags {
  width: 960px;
  height: 540px;
  border: 2px solid #222;
  position: relative;
}

.carvasflag {
  margin: 0 auto;
  background-color: #000;
  z-index: 0;
  width: 303px !important;
  height: 540px !important;
  background-size: 100% 100%;
}

.imges {
  width: 100%;
  height: 100%;
}

.flot {
  height: 100%;
  position: sticky;
  top: 0px;
}

.bottom {
  width: 100%;
  .bottombtn {
    float: right;
    margin-right: 10px;
  }
}
.pptlistas {
  width: 15%;
  height: 100%;
  overflow-y: auto;
  background-color: #26263c;
  box-sizing: border-box;
  box-shadow: -2px 2px 2px 2px;
}
.bottoms {
  margin: 2px auto 0;
  width: 100%;
  height: 28vh;
  background-color: #000;
  padding: 1vh 20px 0px;
  border: 3px solid #222222;
  box-sizing: border-box;

  .bottomsform {
    color: #fff;

    .bottomsformtop {
      margin-bottom: 1px;
      height: 4vh;
      width: 100%;
      margin-bottom: 5px;
    }

    .bottomsformleft {
      float: left;
      width: 30%;
      display: flex;
      justify-content: space-between;

      .bottomsformleftringht {
        float: right;
        line-height: 28px;
      }
    }

    .bottomsformtopright {
      float: right;
      display: flex;
      width: 70%;
      height: 4vh;
      overflow: hidden;
      justify-content: space-around;
    }

    .bottomsformtoprightleft {
      display: flex;
    }

    .formtextarea {
      box-shadow: #ffffff 2px;
    }

    .el-form-item {
      margin-bottom: 0;
    }
  }
}

.panetext {
  display: block;
  width: 70px;
  text-align: left;
}
.my-class {
  border: none;
  position: absolute;
}
.my-dragging-class {
  border: 1px #26263c dashed;
  position: absolute;
}
</style>

<style>
.bottomsform .formtextarea .el-textarea__inner {
  background: #222222;
  color: #fff;
  border: none;
}

.tabssab .el-tabs--border-card {
  background-color: #222222;
}

.tabssab .el-tabs--border-card > .is-left {
  border-right: 1px solid !important;
  border-bottom: none !important;
  height: 100% !important;
}

.tabssab .el-tabs--border-card > .el-tabs__header {
  height: 850px !important;
  width: 30% !important;
  background: #000000;
}

.tabssab > .el-tabs--border-card {
  border: none !important;
}

.backs {
  background-color: rgb(34, 34, 34);
}
</style>